package fr.labri.macchiato.feature.googleShopping;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.util.JSON;

import fr.labri.macchiato.core.api.AbstractFinder;
import fr.labri.macchiato.core.model.Article;
import fr.labri.macchiato.core.model.BusinessEntity;
import fr.labri.macchiato.core.model.Offer;
import fr.labri.macchiato.core.model.Product;
import fr.labri.macchiato.core.technical.Callback;

public class GoogleProductsFinder extends AbstractFinder {

	private GoogleQueryLauncher queryLauncher;

	public GoogleProductsFinder(String url, String name, String urlIcon) {
		super(url, name, urlIcon);
		queryLauncher = new GoogleQueryLauncher(getUrl());
	}

	public void getArticles(String keyword,
			final Callback<List<Article>> callback) {

		queryLauncher.launchQueryForArticles(keyword,
				new AsyncCallback<String>() {

					public void onSuccess(String result) {

						List<Article> articles = decodeArticles(result);
						callback.onCallback(articles);
					}

					public void onFailure(Throwable caught) {
						callback.onFailure(caught);
					}
				});
	}

	private List<Article> decodeArticles(String result) {

		List<Article> articles = new ArrayList<Article>();
		JSONObject rootObject = new JSONObject(JSON.decode(result));

		JSONArray items = rootObject.get("items").isArray();

		for (int i = 0; i < items.size(); ++i) {
			JSONObject metaProduct = (JSONObject) items.get(i);
			if (metaProduct != null) {
				JSONObject jsonProduct = (JSONObject) metaProduct
						.get("product");
				JSONString title = (JSONString) jsonProduct.get("title");
				JSONString gtin = (JSONString) jsonProduct.get("gtin");
				String ean = "";
				if (gtin != null) {
					ean = gtin.stringValue();
					ean = format13EAN(ean);
					Article art = new Article(ean, title.stringValue());
					articles.add(art);
				}
			}
		}
		return articles;
	}

	/**
	 * @param ean
	 */
	String format13EAN(String ean) {
		int size = ean.length();
		if (size == 13)
			return ean;
		if (size > 13)
			return ean.substring(size - 13);
		else
			return format13EAN("0000000000000" + ean);
	}

	public void getOffers(final String ean, List<BusinessEntity> providers,
			final Callback<List<Offer>> callback) {
		queryLauncher.launchQueryForOffers(ean, new AsyncCallback<String>() {

			public void onSuccess(String result) {

				List<Offer> offers = decodeOffers(result, ean);
				callback.onCallback(offers);
			}

			public void onFailure(Throwable caught) {
				callback.onFailure(caught);
			}
		});
	}

	private List<Offer> decodeOffers(String jsonString, String ean) {
		List<Offer> offers = new ArrayList<Offer>();

		JSONObject root = new JSONObject(JSON.decode(jsonString));

		JSONArray items = root.get("items").isArray();

		for (int i = 0; i < items.size(); ++i) {
			JSONObject metaProduct = (JSONObject) items.get(i);
			Offer offer = null;
			if (metaProduct != null) {
				JSONObject jsonProduct = (JSONObject) metaProduct
						.get("product");
				JSONString title = (JSONString) jsonProduct.get("title");

				Article art = new Article(ean, title.stringValue());

				JSONObject author = (JSONObject) jsonProduct.get("author");
				JSONString merchantName = (JSONString) author.get("name");

				BusinessEntity provider = new BusinessEntity(
						merchantName.toString());
				offer = new Offer(art, provider, 0.0);

				JSONArray inventories = (JSONArray) jsonProduct
						.get("inventories");
				for (int k = 0; k < inventories.size(); k++) {
					JSONObject merchant = (JSONObject) inventories.get(k);
					if (merchant != null) {
						JSONNumber price = (JSONNumber) merchant.get("price")
								.isNumber();
						offer.setPrice(price.doubleValue());
					}
				}
			}
			offers.add(offer);
		}
		return offers;
	}

	public void getCheaperOffer(Product product, Callback<Product> callback) {
		// TODO Auto-generated method stub

	}

	public void getBusinessEntities(Callback<List<BusinessEntity>> callback) {
		// TODO Auto-generated method stub

	}

//	public String getName() {
//		return "Google";
//	}
//
//	public String getUrlIcon() {
//		return "http://static.commentcamarche.net/www.commentcamarche.net/faq/images/14175-google-logo-3-s-.png";
//	}
}
